<template>
  <div>
    <h1>{{ obj.b.c }}</h1>
    <h1>{{ g.d.f }}</h1>
    <h1>{{ nomarl.name }}</h1>
    <h1>{{ cf }}</h1>
    <button @click="change">改变</button>
    <button @click="changeData">改变</button>
    <button @click="changePRO">改变provide</button>
    <hr />
    <other-son></other-son>
  </div>
</template>
<script>
import {
  readonly,
  shallowReadonly,
  toRefs,
  toRef,
  customRef,
  ref,
  reactive,
  shallowReactive,
  shallowRef,
  toRaw,
  provide
} from 'vue'
import otherSon from './othSon.vue'
export default {
  components: { otherSon },
  setup (props) {
    // shallowReactive : 只处理了对象内
    // 最外层属性的响应式(也就是浅响应式)
    // shallowRef: 只处理了value的响应式,
    //  不进行对象的reactive处理
    let obj = shallowRef({ a: '你好', b: { c: '星期五' } })
    let datas = shallowReactive({
      k: '11',
      g: { d: { f: '闪现' } }
    })
    //     readonly: 深度只读数据
    //   获取一个对象 (响应式或纯对象) 或 ref
    //   并返回原始代理的只读代理。

    //   只读代理是深层的：访问的任何嵌套 property 也是只读的。
    // shallowReadonly: 浅只读数据
    let change = () => {
      obj.value.b.c = '星期六'
      datas.g.d.f = '引燃'
    }
    let sta = reactive({
      list: [1, 2, 3],
      name: '小王'
    })
    let re = readonly(sta)
    // toRaw
    // 返回由 reactive 或 readonly
    // 方法转换成响应式代理的普通对象。
    let nomarl = reactive({
      name: '王德发',
      age: 18
    })
    let changeData = () => {
      let cc = toRaw(nomarl)
      cc.name = '富贵'
    }
    //
    let cname = ref('罗纳尔多')
    provide('cname', cname)
    let changePRO = () => {
      cname.value = '莱万'
    }
    //markRaw
    // 标记一个对象，使其永远不会转换为代理。
    //   返回对象本身
    // toRef
    // 区别ref: 拷贝了一份新的数据值单独操作, 更新时相互不影响
    const state = reactive({
      foo: 1,
      bar: 2
    })

    const foo = toRef(state, 'foo')
    const foo2 = ref(state.foo)
    let cf = Myref(18)
    let ff = Myref(98)
    // customRef 自定义ref
    function Myref (value) {
      return customRef((track, trigger) => {
        return {
          get () {
            // 告诉vue去追踪数据
            track()
            return value + 2
          },
          set (newValue) {
            // 告诉Vue去触发界面更新
            trigger()
          }
        }
      })
    }
    return {
      changePRO,
      cf,
      nomarl,
      changeData,
      re,
      change,
      obj,
      ...toRefs(datas)
    }
  }
}
</script>
